﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LensflareGameFramework;
using Microsoft.Xna.Framework;
using Util;
using Microsoft.Xna.Framework.Graphics;

namespace Hexacell {
    public class Board : Entity {
        protected Game1 game;
        protected List<CellTransition> cellTransitions = new List<CellTransition>();

        public Vector2 Position { get; set; }
        public IntVector2 CellCount { get; protected set; }
        public bool HalfRow { get; protected set; }
        public float CellRadius { get; set; }

        public Board(Game1 game, int cellCountX, int cellCountY, bool halfRow) {
            this.game = game;

            CellCount = new IntVector2(cellCountX, cellCountY);
            HalfRow = halfRow;
        }

        protected int columnWidth() {
            return (int)(Math.Sqrt(3) * CellRadius);
        }

        protected Vector2 centerOfCell(IntVector2 coordinates) {
            float r = CellRadius;

            float offsetY = 0;
            bool columnIsEven = coordinates.X % 2 == 0;
            if (!columnIsEven) {
                offsetY = r;
            }

            return Position + new Vector2(r + columnWidth() * coordinates.X, r + 2 * r * coordinates.Y + offsetY);
        }

        protected List<IntVector2> neighbors(IntVector2 cell) {
            List<IntVector2> neighbors = new List<IntVector2>();
            int x = cell.X;
            int y = cell.Y;

            if (y > 0) {
                neighbors.Add(new IntVector2(x, y - 1));
            }
            if (y < CellCount.Y - 1) {
                neighbors.Add(new IntVector2(x, y + 1));
            }

            if (x > 0) {
                neighbors.Add(new IntVector2(x - 1, y));
                if (x % 2 == 0) {
                    if (y > 0) {
                        neighbors.Add(new IntVector2(x - 1, y - 1));
                    }
                } else {
                    if (y < CellCount.Y - 1) {
                        neighbors.Add(new IntVector2(x - 1, y + 1));
                    }
                }
            }
            if (x < CellCount.X - 1) {
                neighbors.Add(new IntVector2(x + 1, y));
                if (x % 2 == 0) {
                    if (y > 0) {
                        neighbors.Add(new IntVector2(x + 1, y - 1));
                    }
                } else {
                    if (y < CellCount.Y - 1) {
                        neighbors.Add(new IntVector2(x + 1, y + 1));
                    }
                }
            }

            return neighbors;
        }

        protected IntVector2? hoveredCellCoordinates_bak1() {
            int x = (int)((Input.MousePosition.X-Position.X) / columnWidth());
            int y = (int)((Input.MousePosition.Y-Position.Y) / (CellRadius * 2.0f));
            bool cellExists = x >= 0 && x < CellCount.X && y >= 0 && y < CellCount.Y;
            return cellExists ? (IntVector2?)(new IntVector2(x, y)) : null;
        }

        public IntVector2? hoveredCellCoordinates() {
            int xPick = 0;
            int yPick = 0;
            float minDist = float.PositiveInfinity;
            for (int y = 0; y < CellCount.Y; ++y) {
                for (int x = 0; x < CellCount.X; ++x) {
                    Vector2 cell = centerOfCell(new IntVector2(x,y));
                    Vector2 mouse = Input.MousePosition;
                    float dx = cell.X - mouse.X;
                    float dy = cell.Y - mouse.Y;
                    float distSquared = dx * dx + dy * dy; //TODO: Vector2.DistanceSquared()
                    if (distSquared < minDist) {
                        xPick = x;
                        yPick = y;
                        minDist = distSquared;
                    }
                }
            }
            return (IntVector2?)(new IntVector2(xPick, yPick));
        }

        //protected Vector2 directionFromCellToCell(IntVector2 src, IntVector2 dest) {}

        override protected void Dispose() {

        }

        override public void Update(GameTime gameTime) {

        }

        override public void Draw() {
            SpriteBatch spriteBatch = game.SpriteBatch;
            float r = CellRadius;
            
            float layerDepth = game.LayerManager.Depth((int)MainLayer.Board);

            IntVector2? hovered = hoveredCellCoordinates();
            List<IntVector2> neighborsOfHovered = hovered.HasValue ? neighbors(hovered.Value) : new List<IntVector2>();

            for (int y = 0; y < CellCount.Y; ++y) {
                for (int x = 0; x < CellCount.X; ++x) {
                    Color color = Color.Orange;

                    IntVector2 cell = new IntVector2(x, y);

                    bool cellIsHovered = hovered.HasValue && hovered.Value == cell;

                    if (cellIsHovered) {
                        color = Color.Green;
                    }

                    if (neighborsOfHovered.Contains(cell)) {
                        color = Color.Red;
                    }

                    Vector2 position = centerOfCell(cell);
                    Primitive2.DrawCircle(spriteBatch, position, r - 1, color, true, layerDepth);
                }
            }
        }
    }
}
